package cn.tianyigps.m7.analyze;

import cn.tianyigps.m7.beans.StandardModel;
import cn.tianyigps.m7.utils.DataFormatUtil;
import cn.tianyigps.m7.utils.MessageCoding;
import cn.tianyigps.m7.utils.StringAnalysisUtil;

import java.math.BigInteger;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author: LiuHao
 * @Descirption: 数据解析处理类
 * @Date: 2019/4/16_9:22
 */
public class DataAnalyze {

    /**
     * 报警包解析
     * @param body
     */
    public static StandardModel alarmAnalyze(String body) {
        StandardModel standardModel = new StandardModel();
        Map<String, Object> extend = new HashMap<>();
        standardModel.setExtend(extend);

        Date date = DataFormatUtil.formatDate(body.substring(0,12));//GPS 信息 日期时间 6
        standardModel.setLocateTime(date);
        body = body.substring(12);

        analyzeGpsInfo(body.substring(0,24), standardModel);//GPS信息 12
        body = body.substring(24);

        String lbsLength = DataFormatUtil.hexadecimalTODecimalString(body.substring(0,2));//LBS长度 1
        extend.put("lbsLength",lbsLength);
        body = body.substring(2);

        analyzeLbsInfo(body.substring(0,16), standardModel);//LBS信息 8
        body = body.substring(16);

        extend.putAll(analyzeStatusInfo(body.substring(0,6)));
        body = body.substring(6);


        extend.put("alarmInfo",body.substring(0,2));//报警/语言/扩展口状态2
        body = body.substring(2);
        extend.put("language",body.substring(0,2));


        return standardModel;
    }

    public static StandardModel analysisReplyPackage(String data) {

        StandardModel standardModel = new StandardModel();
        Map<String, Object> extend = new HashMap<>();
        standardModel.setExtend(extend);
        String contentCodeType = data.substring(8, 10);
        String content = data.substring(10,data.length());

        if ("01".equals(contentCodeType)){
            //编码(使用GB2312解码，兼容ascll不需要做转换，其中指令的长度包含了服务器标识位，需要剔除这四个字节)
            content = MessageCoding.convertHexToString(content);
        }else if ("02".equals(contentCodeType)){
            content = StringAnalysisUtil.convertHexToStringByUtf_16BE(content);
        }
        extend.put("content",content);
        return standardModel;
    }

    /**
     * 仅LBS定位包解析
     * @param body
     */

    public static StandardModel lbsInfoAnalyze(String body) {

        StandardModel standardModel = new StandardModel();
        Map<String, Object> extend = new HashMap<>();
        standardModel.setExtend(extend);
        Date reportTime = DataFormatUtil.formatDate(body.substring(0,12));//日期 6
        standardModel.setLocateTime(reportTime);
        body = body.substring(12);

        String ta = DataFormatUtil.hexadecimalTODecimalString(body.substring(0,2));//TA  1
        extend.put("ta",ta);
        body = body.substring(2);

        String mcc = DataFormatUtil.hexadecimalTODecimalString(body.substring(0,4));//MCC 2
        extend.put("mcc",mcc);
        body = body.substring(4);

        String mnc = DataFormatUtil.hexadecimalTODecimalString(body.substring(0,2));//MNC 1
        extend.put("mnc",mnc);
        body = body.substring(2);

        String cellNumber = DataFormatUtil.hexadecimalTODecimalString(body.substring(0,2));//CELL NUMBER 1
        extend.put("cellNumber",cellNumber);
        body = body.substring(2);
        BigInteger bigInteger = DataFormatUtil.hexadecimalTODecimal(cellNumber);
        int cellNum = bigInteger.intValue();
        analyzeLbsBaseStation(standardModel,body,cellNum);
        return standardModel;
    }

    /**
     * 心跳包解析
     * @param body
     */
    public static StandardModel heartBeatAnalyze(String body) {
        StandardModel standardModel = new StandardModel();
        Map<String,Object> extend = new HashMap<>();
        standardModel.setExtend(extend);
        String terminalInfo = DataFormatUtil.hexadecimalTOBinary(body.substring(0,2));//终端信息内容 1
        extend.putAll(analyzeTerminalInfo(terminalInfo));
        body = body.substring(2);

        String voltageLevel = body.substring(0,2);//电压等级  1
        extend.put("voltageLevel",voltageLevel);
        body = body.substring(2);

        extend.put("GSMSignal",body.substring(0,2));//GSM信号强度 1
        body = body.substring(2);

        //报警/语言/扩展口状态2
        if(voltageLevel.startsWith("F")){
            String data = voltageLevel.substring(1)+body.substring(0,2);
            double voltage = DataFormatUtil.hexadecimalTODecimal(data).doubleValue() / 10;
            extend.put("voltage",voltage);//扩展口状态，外接电源 取电压值
        }else{
            extend.put("voltage","00");//扩展口状态 非外接电源 取状态码
        }
        body = body.substring(2);
        extend.put("language",body.substring(0,2));


        return standardModel;
    }

    /**
     * 定位包解析
     * @param body
     */
    public static StandardModel locationAnalyze(String body) {
        StandardModel standardModel = new StandardModel();
        Map<String,Object> extend = new HashMap<>();
        standardModel.setExtend(extend);
        Date date = DataFormatUtil.formatDate(body.substring(0,12));//日期时间 6
        standardModel.setLocateTime(date);
        body = body.substring(12);

        analyzeGpsInfo(body.substring(0,24), standardModel);//GPS信息 12
        body = body.substring(24);

        analyzeLbsInfo(body.substring(0,16), standardModel);//LBS信息 8
        body = body.substring(16);

        String acc = body.substring(0,2);//ACC 1  ACC 低为 00 ， ACC 高为 01
        extend.put("acc",acc);
        body = body.substring(2);

        String reportMode = body.substring(0,2);//数据上报模式 1
        extend.put("reportMode",reportMode);
        body = body.substring(2);

//GPS 实时补传 1 0x00 实时上传 0x01 补传
        String rtr = body.substring(0,2);
        extend.put("rtr",rtr);
        standardModel.setRtr(rtr);
        return standardModel;
    }


    /**
     * 登录包解析
     * @param body
     */
    public static StandardModel loginAnalyze(String body) {
        StandardModel standardModel = new StandardModel();
        Map<String,Object> extend = new HashMap<>();
        standardModel.setExtend(extend);
        String equipmentId = body.substring(0, 16);//终端ID
        equipmentId = equipmentId.replaceFirst("^0*", "");
        standardModel.setEquipmentId(equipmentId);
        body = body.substring(16);
        String typeIdentifyCode = body.substring(0, 4);//类型识别码
        extend.put("typeIdentifyCode", typeIdentifyCode);
        return standardModel;
    }
    /**
     * iccid包解析
     * @param body
     */
    public static StandardModel iccidAnalyze(String body) {
        StandardModel standardModel = new StandardModel();
        Map<String,Object> extend = new HashMap<>();
        standardModel.setExtend(extend);
        String substring = body.substring(0, 2);
        if ("0A".equals(substring)) {
            extend.put("iccid", body.substring(34, 54));
        }
        return standardModel;
    }

    /**
     * 基站信息解析
     *
     * @param standardModel
     * @param data
     * @return
     */
    public static void analyzeLbsBaseStation(StandardModel standardModel, String data, Integer cellNum){

        String lac = null;
        String cellId = null;
        Integer maxRssi = -1;
        for (int i = 0; i < cellNum ; i++) {
            String laci = DataFormatUtil.hexadecimalTODecimalString(data.substring(0,4));//LAC
            data = data.substring(4);
            String cellIdi = DataFormatUtil.hexadecimalTODecimalString(data.substring(0,6));//CELL ID
            data = data.substring(6);
            Integer rssi = - DataFormatUtil.hexadecimalTODecimal(data.substring(0,2)).intValue();//RSSI
            data = data.substring(2);
            if (rssi > maxRssi){
                lac = laci;
                cellId = cellIdi;
                maxRssi = rssi;
            }
        }
        standardModel.setLac(lac);
        standardModel.setCellId(cellId);
        standardModel.setLocationType("01");
    }

    /**
     * 状态信息解析
     * @param statusInfo
     */
    private static Map<String,Object> analyzeStatusInfo(String statusInfo) {

        Map<String,Object> alarm = new HashMap<>();
        String terminalInfo = DataFormatUtil.hexadecimalTOBinary(statusInfo.substring(0,2));//终端信息内容 1
        alarm.putAll(analyzeTerminalInfo(terminalInfo));
        statusInfo = statusInfo.substring(2);

        alarm.put("voltageLevel",statusInfo.substring(0,2));//电压等级  1
        statusInfo = statusInfo.substring(2);

        alarm.put("GSMSignal",statusInfo.substring(0,2));//GSM信号强度 1
        return alarm;
    }

    /**
     * 终端信息解析
     * @param terminalInfo
     */
    private static Map<String,Object> analyzeTerminalInfo(String terminalInfo) {
        Map<String,Object> alarm = new HashMap<>();
        alarm.put("oilGas",terminalInfo.substring(0,1));//油电
        terminalInfo = terminalInfo.substring(1);
        alarm.put("hasGpsPositioned",terminalInfo.substring(0,1));//gps是否定位 0否1是
        terminalInfo = terminalInfo.substring(1);
        alarm.put("alarmStatus",terminalInfo.substring(0,3)); //报警状态
        terminalInfo = terminalInfo.substring(3);
        alarm.put("isPowerOn",terminalInfo.substring(0,1)); //是否接通电源 0否1是
        terminalInfo = terminalInfo.substring(1);
        alarm.put("acc",terminalInfo.substring(0,1));//是否为高ACC 0否1是
        terminalInfo = terminalInfo.substring(1);
        alarm.put("hasFortification",terminalInfo.substring(0,1)); //是否设防 0否1是
        return alarm;
    }


    /**
     * lbs信息解析
     * @param lbsInfo
     * @param standardModel
     */
    private static void analyzeLbsInfo(String lbsInfo, StandardModel standardModel) {
        Map<String,Object> extend = new HashMap<>();
        String mcc = DataFormatUtil.hexadecimalTODecimalString(lbsInfo.substring(0,4));//LBS 信息 MCC 2
        extend.put("mcc",mcc);
        lbsInfo = lbsInfo.substring(4);

        String mnc = DataFormatUtil.hexadecimalTODecimalString(lbsInfo.substring(0,2));//LBS 信息 MNC 1
        extend.put("mnc",mnc);
        lbsInfo = lbsInfo.substring(2);

        String lac = DataFormatUtil.hexadecimalTODecimalString(lbsInfo.substring(0,4));//LBS 信息 LAC 2
        standardModel.setLac(lac);
        lbsInfo = lbsInfo.substring(4);

        String cellId = DataFormatUtil.hexadecimalTODecimalString(lbsInfo.substring(0,6));//LBS 信息 Cell ID 3
        standardModel.setCellId(cellId);
        standardModel.getExtend().putAll(extend);
    }

    /**
     * GPS信息解析
     * @param gpsInfo
     * @param standardModel
     * @return
     */
    public static void analyzeGpsInfo(String gpsInfo, StandardModel standardModel){
        Map<String,Object> extend = new HashMap<>();

        String gpsInfoLength = DataFormatUtil.hexadecimalTODecimalString(gpsInfo.substring(0,1));//GPS 长度
        extend.put("gpsInfoLength",gpsInfoLength);
        gpsInfo = gpsInfo.substring(1);

        String satellites = DataFormatUtil.hexadecimalTODecimalString(gpsInfo.substring(0,1));//GPS 卫星数
        extend.put("satellites",satellites);
        gpsInfo = gpsInfo.substring(1);
        standardModel.getExtend().putAll(extend);

        double gpsLatitude = DataFormatUtil.getLatOrLon(gpsInfo.substring(0,8));//GPS 信息 纬度 4
        standardModel.setGpsLatitude(gpsLatitude);
        gpsInfo = gpsInfo.substring(8);

        double gpsLongitude = DataFormatUtil.getLatOrLon(gpsInfo.substring(0,8));//GPS 信息 经度 4
        standardModel.setGpsLongitude(gpsLongitude);
        gpsInfo = gpsInfo.substring(8);

        double speed = DataFormatUtil.hexadecimalTODecimalDouble(gpsInfo.substring(0,2));//GPS 信息  速度 1
        standardModel.setSpeed(speed);
        gpsInfo = gpsInfo.substring(2);

        analyzeHeading(gpsInfo.substring(0,4), standardModel);//GPS 信息  航向、状态 2(车辆航向)
    }

    /**
     * GPS航向信息
     * @param headingData
     * @param standardModel
     * @return
     */
    private static void analyzeHeading(String headingData, StandardModel standardModel){
        Map<String,Object> extend = new HashMap<>();
        String binaryContent = DataFormatUtil.hexadecimalTOBinary(headingData);//转换为二进制字符串
        extend.put("positionType",binaryContent.substring(2,3));//GPS 实时/差分定位
        String hasPositioned = binaryContent.substring(3, 4);
        extend.put("hasPositioned", hasPositioned);//GPS定位与否
        if("1".equals(hasPositioned))
            standardModel.setLocationType("00");
        else
            standardModel.setLocationType("01");

        extend.put("longitudeType",binaryContent.substring(4,5));//东经西经
        extend.put("latitudeType",binaryContent.substring(5,6));//南纬北纬
        String heading = DataFormatUtil.binaryTODecimal(binaryContent.substring(6));//航向
        standardModel.setHeading(heading);
        standardModel.getExtend().putAll(extend);
    }

}
